﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Sublimation
{
    public class SlotLightning : SlotWeapon
    {
        protected int NUMBER_OF_FRAMES_TO_PLAY = 4;
        protected int FRAMES_PER_SECOND = 20;
        protected AnimatedSprite.AnimatedTexture textureLightning;


        protected SlotLightning connectedSlot;
        protected SlotLightning targetSlot;
        protected List<SlotLightning> destinations;
        public List<SlotLightning> Destinations
        {
            get { return destinations; }
            set { destinations = value; }
        }
        public SlotLightning(WorldProperties worldProperties, SlotKind kind, Tower ownerTower)
            : base(worldProperties, kind, ownerTower,false)
        {
            rangeDisplayColor = Color.Blue;
            RangedFlightSpeed = 1500;
            UpdateOrder = 60;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            if (connectedSlot != null)
            {
                textureLightning.UpdateFrame((float)gameTime.ElapsedGameTime.TotalSeconds);
            }
        }
        public override GameObject getTarget()
        {
            connectedSlot = null;
            targetSlot = null;
            lookForConnection();
            foreach (SlotLightning slot in destinations)
            {
                 
                if (slot.destinations != null)
                {
                    float distance=0;
                    SlotLightning closestSlot=null;
                    foreach (SlotLightning slot2 in slot.destinations)
                    { 
                        if (slot2 == this )
                        {
                            if(closestSlot ==null || Vector2.Distance(slot.position,Position)<distance){

                                distance = Vector2.Distance(slot.position, Position);
                                closestSlot  = slot;
                            }                            
                        }
                    }
                    if(closestSlot != null ){
                        if (closestSlot.targetSlot == this)
                        {
                            this.targetSlot = closestSlot;
                            Connection(closestSlot);
                        }
                        else
                        {
                            this.targetSlot = closestSlot;
                        }
                    }
                }
            }
            return null;
        }

        protected void lookForConnection()
        {
            destinations = new List<SlotLightning>();
            foreach (Tower tower in worldProperties.Players[0].Towers)
            {
                foreach (Slot slot in tower.Slots)
                {
                    if (slot.Kind == SlotKind.Lightning && !slot.Building)
                    {
                        //get the angle with the enemy
                        Vector2 direction = tower.Position - ownerTower.Position;
                        direction.Normalize();
                        direction.Y = -direction.Y;
                        float angle_direction;
                        if (direction.Y >= 0)
                        {
                            angle_direction = (float)Math.Acos(direction.X) % MathHelper.TwoPi;
                        }
                        else
                        {
                            angle_direction = -(float)Math.Acos(direction.X) % MathHelper.TwoPi;
                        }
                        //make sure it's between 0 and 2 PI
                        if (angle_direction < 0)
                        {
                            angle_direction += MathHelper.TwoPi;
                        }


                        float aimingAngle = ownerTower.Rotation + orientation;
                        //get the minimum angle
                        float min_angle = ((-aimingAngle - angle)) % MathHelper.TwoPi;
                        //make sure it's between 0 and 2 PI
                        if (min_angle < 0)
                        {
                            min_angle += MathHelper.TwoPi;
                        }

                        //get the maximum angle
                        float max_angle = ((-aimingAngle + angle)) % MathHelper.TwoPi;
                        //get sure it's between 0 and 2 PI
                        if (max_angle < 0)
                        {
                            max_angle += MathHelper.TwoPi;
                        }

                        bool isTarget = false;
                        if (max_angle < min_angle)
                        {
                            if (angle_direction < max_angle || angle_direction > min_angle && angle_direction > max_angle)
                            {
                                isTarget = true;
                            }
                        }
                        else
                        {
                            if (angle_direction < max_angle && angle_direction > min_angle)
                            {
                                isTarget = true;
                            }
                        }
                        if (isTarget)
                        {
                            destinations.Add((SlotLightning)slot);
                        }
                    }
                }
            }
        }

        public void Connection(SlotLightning slot)
        {
            float X1, X2, Y1, Y2, a, b, distance;

            if (slot.Position.X > Position.X)
            {
                connectedSlot = slot;
                X1 = Position.X;
                X2 = slot.Position.X;
                Y1 = Position.Y;
                Y2 = slot.Position.Y;
            }
            else
            {
                X1 = Position.X;
                X2 = slot.Position.X;
                Y1 = Position.Y;
                Y2 = slot.Position.Y;
            }
            a = -(Y2 - Y1) / (X2 - X1);
            textureLightning.Rotation = -(float)Math.Atan(a) - MathHelper.PiOver2;
            b = -(Y1 + a * X1);
            foreach (EnemyUnit enemy in worldProperties.Enemies)
            {
                if (enemy.Position.X > X1 && enemy.Position.X < X2)
                {
                    distance = (float)(Math.Abs(a * enemy.Position.X + enemy.Position.Y + b) / Math.Sqrt(a * a + 1));
                    if (distance < enemy.CollisionRadius+15)
                    {
                        enemy.ApplyDamage(damageAffected);
                        new Animation(worldProperties, enemy, enemy.CollisionRadius * 0.03f, 4, 10, "Sprites\\bullet_hit_enemy-1");
                    }
                }
            }
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            Sprite = Game.Content.Load<Texture2D>("Sprites/lightening_fence_1");
            textureLightning = new AnimatedSprite.AnimatedTexture(Origin, Rotation, 1.0f, 1.0f);
            textureLightning.Load(Game.Content, "Sprites\\bullet_lightning",NUMBER_OF_FRAMES_TO_PLAY, FRAMES_PER_SECOND);
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            if (connectedSlot != null)
            {
                textureLightning.Scale = Vector2.Distance(position, connectedSlot.position) / 594;
                textureLightning.Origin = new Vector2(20f,-40f*Scale);
                spriteBatch.Begin();
                textureLightning.DrawFrame(spriteBatch, Position);
                spriteBatch.End();
            }
        }

    }
}

